<script>

import {getCurrentInstance, nextTick, onMounted, ref, watch} from "vue";
import Header from "../../components/HeaderVue.vue";
import {
  ChatRound,
  Connection,
  DArrowRight,
  Discount,
  EditPen,
  Mic,
  RefreshRight,
  Switch,
  UploadFilled
} from "@element-plus/icons-vue";
import {
  aiCorrectionError, aiTextRewrite,
  characterRecognition,
  formulaRecognition, getAiPPTLink,
  getAiRecommendWord,
  getBase64LinkByUID, getPptTheme,
  getRandomSpeechText, getToolFrequency,
  machineTranslate,
  photoCalculate,
  pictureDocument, updateToolFrequency,
  uploadAudioFile
} from "../../../api/toolbar/ToolBar.js";
import Recorder from "recorder-core";
import {ElLoading, ElMessage} from "element-plus";
import {fetchEventSource} from "@microsoft/fetch-event-source";

export default {
  name: "ToolBar",
  computed: {
    DArrowRight() {
      return DArrowRight
    }
  },
  components: {
    RefreshRight,
    UploadFilled,
    Discount,
    EditPen,
    ChatRound,
    Connection,
    Mic,
    Switch,
    Header
  },
  setup() {
    /*----------------变量------------------*/
    // 竖状导航栏下标
    let tabIndex = ref('1');
    // 起始语言
    let fromLanguage = ref('');
    // 目标语言
    let toLanguage = ref('');
    // 待翻译文本
    let fromText = ref('');
    // 翻译后文本
    let toText = ref('');
    // ai推荐的单词列表
    let wordList = ref('');
    // 需要纠正的句子
    let needCorrectWord = ref('');
    // ai纠错后返回的结果
    let aiCorrectErrorList = ref('');
    // 上传图片后获取的UID
    let UID = ref('');
    // 图片转公式后 获得的公式
    let formula = ref('');
    // 图片转电子稿时目标文件类型
    let targetFileType = ref("0");
    // 图片转化为电子稿时所需要的文件后缀
    let uploadFileType = ref('');
    // 图片转电子稿后电子稿的下载路径
    let downloadLink = ref('');
    // 图片转文字后识别出来的文字
    let textResult = ref('');
    // 语音评测当前题目种类
    let category = ref('read_word');
    // 语音评测当前题目
    let text = ref('');
    // 文本改写的改写等级
    let rewriteLevel = ref('<L1>');
    // 文本改写初始文本
    let initText = ref('');
    // 文本改写改后的文本
    let correctText = ref('');
    // 用户对各个功能调用频率list
    let frequencyList = ref([0, 0, 0, 0, 0, 0, 0, 0, 0]);
    // 通过 internalInstance.appContext.config.globalProperties 获取全局属性或方法
    let internalInstance = getCurrentInstance();
    let echarts = internalInstance.appContext.config.globalProperties.$echarts;
    // 当前是否有音频在播放
    let audioPlaying = false;
    // 语音合成 全部音频的base64链接
    let base64Array = [];
    // 自动批改是否批改完毕
    let hasJudged = ref(false);
    // 自动批改时上传的文件的原始宽度和原始高度
    let imgWidth = 0;
    let imgHeight = 0;
    // ppt主题
    let pptTheme = ref('');
    // ppt作者名
    let pptAuthor = ref();
    // ppt生成类型
    let pptType = ref();
    // ppt要求
    let pptTopic = ref();
    // 是否生成ppt演讲备注
    let isGeneratePPTSpeech = ref(false);
    // 是否生成封面
    let isGenerateCover = ref(false);
    // ai生成ppt中可以生成的ppt主题封面
    let allPPtCover = ref([])
    // ai生成ppt中可以生产的ppt主题关键词
    let allPPtTheme = ref([]);
    // 语音评测结果
    let evaluationResult = ref([])
    // 翻译语言列表
    const translateList = ref([{
      value: 'cn',
      label: '中文'
    }, {
      value: 'en',
      label: '英文'
    }, {
      value: 'ja',
      label: '日语'
    }, {
      value: 'ko',
      label: '韩语'
    }, {
      value: 'fr',
      label: '法语'
    }, {
      value: 'es',
      label: '西班牙语'
    }, {
      value: 'ru',
      label: '俄语'
    }, {
      value: 'de',
      label: '德语'
    }, {
      value: 'vi',
      label: '越南语'
    }, {
      value: 'th',
      label: '泰语'
    }, {
      value: 'ar',
      label: '阿拉伯语'
    }, {
      value: 'hi',
      label: '印地语'
    }])
    /*---------------常规方法----------------*/
    function handleSelect(index) {
      tabIndex.value = index;
    }
    // 当上传文件完成后
    function handleUploadImage(file) {
      UID.value = file.data
    }
    // 上传文件之前 获取上传文件的后缀
    function getUploadFileType(file) {
      uploadFileType.value = file.name.split('.')[1]
    }
    // 点击下载按钮下载转换后的电子稿
    function downloadFile() {
      var a = document.createElement("a");
      var event = new MouseEvent("click");
      // 将生成的URL设置为a.href属性
      a.href = downloadLink.value;
      // 触发a的单击事件
      a.dispatchEvent(event);
      a.remove();
    }
    // 复制内容到剪贴板
    function copyToClipboard(text) {
      var dummy = document.createElement("textarea");
      document.body.appendChild(dummy);
      dummy.value = text;
      dummy.select();
      document.execCommand("copy");
      document.body.removeChild(dummy);
    }
    function recOpen(){
      //创建录音对象
      this.rec=Recorder({
        type:"mp3" //录音格式，可以换成wav等其他格式
        ,sampleRate:16000 //录音的采样率，越大细节越丰富越细腻
        ,bitRate:16 //录音的比特率，越大音质越好
      });

      //打开录音，获得权限
      this.rec.open(()=>{
        console.log("录音已打开");
      },(msg,isUserNotAllow)=>{
        //用户拒绝了录音权限，或者浏览器不支持录音
        console.log((isUserNotAllow?"UserNotAllow，":"")+"无法录音:"+msg);
      });
    }
    function recStart(){
      if(!this.rec){ console.error("未打开录音");return }
      this.rec.start();
      console.log("已开始录音");
    }
    function recStop(){
      if(!this.rec){ console.error("未打开录音");return }
      this.rec.stop((blob,duration)=>{
        //blob就是我们要的录音文件对象，可以上传，或者本地播放
        this.recBlob=blob;
        //简单利用URL生成本地文件地址，此地址只能本地使用，比如赋值给audio.src进行播放，赋值给a.href然后a.click()进行下载（a需提供download="xxx.mp3"属性）
        var localUrl=(window.URL||webkitURL).createObjectURL(blob);
        console.log("录音成功",blob,localUrl,"时长:"+duration+"ms");

        this.upload(blob);//把blob文件上传到服务器

        this.rec.close();//关闭录音，释放录音资源，当然可以不释放，后面可以连续调用start
        this.rec=null;
      },(err)=>{
        console.error("结束录音出错："+err);
        this.rec.close();//关闭录音，释放录音资源，当然可以不释放，后面可以连续调用start
        this.rec=null;
      });
    }
    function recPlay(){
      //本地播放录音试听，可以直接用URL把blob转换成本地播放地址，用audio进行播放
      var localUrl=URL.createObjectURL(this.recBlob);
      var audio=document.createElement("audio");
      audio.controls=true;
      // 隐藏audio元素
      audio.style.opacity = 0;
      document.body.appendChild(audio);
      audio.src=localUrl;
      audio.play(); //这样就能播放了
      //注意不用了时需要revokeObjectURL，否则霸占内存
      setTimeout(function(){ URL.revokeObjectURL(audio.src) },5000);
    }
    function playNextAudio() {
      // 如果base64Array中还有音频就播放
      if ( base64Array.length > 0 ) {
        audioPlaying = true;
        // shift 删除第一个元素并返回 此方法会改变数组长度
        const nextAudio = base64Array.shift();
        // 播放音频
        const audio = document.createElement('audio');
        audio.setAttribute('src', "data:audio/mp3;base64,"+ nextAudio)
        audio.play();
        audio.onended = function () {
          // 播放结束 设置状态为false
          audioPlaying = false;
          // 播放下一个音频
          playNextAudio();
        }
      }
    }
    // 在图片上传之前 获取图片的宽高 便于自动批改时计算缩放比例
    function getImageHeightAndWidth(file) {
      const reader = new FileReader();
      reader.onload = function(e) {
        const image = new Image();
        image.onload = function() {
          imgWidth = this.width;
          imgHeight = this.height;
          console.log('图片宽度：', imgWidth);
          console.log('图片高度：', imgHeight);
        };
        image.src = e.target.result;
      };
      reader.readAsDataURL(file);
    }
    /*---------------请求方法----------------*/
    // 获取ai生成的ppt链接
    function getAiPPT() {
      if (pptAuthor.value === '') {
        pptAuthor.value = '智文';
      }
      let loadingmsg = ElMessage.warning({
         message: '正在生成PPT，请稍后...',
         type: 'warning',
         icon: 'Loading',
         duration: 0
      })
      let pptProcessMsg = ElMessage({
        message: `当前进度: <progress max="100" value="0" style="width: 100px;" class="progress"></progress>`,
        type: 'info',
        icon: 'InfoFilled',
        duration: 0,
        dangerouslyUseHTMLString: true,
      })
      const controller = new AbortController()
      fetchEventSource('/api/aiChat/getAiPPTWithoutAnything?type=' + pptType.value + '&author=' + pptAuthor.value + '&query=' + pptTopic.value + '&isCardNote=' + isGeneratePPTSpeech.value + '&isCoverImg=' + isGenerateCover.value + '&theme=' + pptTheme.value, {
        method: 'GET',
        headers: {
          'content-type': 'application/json',
          'token': localStorage.getItem("token")
        },
        signal: controller.signal,
        openWhenHidden: true,
        onmessage(event) {
          // 讲event.data转化为json对象
          const response = JSON.parse(event.data);
          const data = response.data;
          let procressDom = document.querySelector('.progress')
          procressDom.setAttribute('value', data.process)
          console.log(data)
          // 生成完成
          if (data.process === 100) {
              var a = document.createElement("a");
              var event = new MouseEvent("click");
              // 将生成的URL设置为a.href属性
              a.href = data.pptUrl;
              // 触发a的单击事件
              a.dispatchEvent(event);
              a.remove();
              loadingmsg.close();
              pptProcessMsg.close();
              controller.abort()
          }
          if (event.data === '&#92n[DONE]') {
            // 发送完成结束对话 删除打字机定时器
            controller.abort();
            return;
          }
        },
        onclose(event) {
          controller.abort();
        },
        onerror(event) {
          ElMessage.error("生成失败，请重试...");
          controller.abort();
        }
      });
      pptType.value = ''
      pptAuthor.value = ''
      pptTopic.value = ''
      pptTheme.value = ''
      isGeneratePPTSpeech.value = false
      isGenerateCover.value = false
      // 更新用户对当前功能的调用频率
      updateToolFrequency(tabIndex.value);
    }
    // 进入页面时 获取ai生成ppt可以生成的主题
    getPptTheme().then(res => {
      for ( let i = 0 ; i < res.data.length ; i ++ ) {
        allPPtCover.value.push(res.data[i].thumbnail);
        allPPtTheme.value.push({ value: res.data[i].key, label: res.data[i].name });
      }
      console.log(res.data)
    })
    // 上传用户说话的内容到后端
    function upload(blob){
      // 获取dom
      let dom = document.querySelector('.oral-result');
      // 在没完成之前改为加载状态
      let loading = ElLoading.service({
        text: '评测结果生成中...',
        spinner: "",
        target: dom,
      })
      //使用FormData用multipart/form-data表单上传文件
      //或者将blob文件用FileReader转成base64纯文本编码，使用普通application/x-www-form-urlencoded表单上传
      var form=new FormData();
      form.append("file",blob,"recorder.mp3"); //和普通form表单并无二致，后端接收到upfile参数的文件，文件名为recorder.mp3
      form.append("text",text.value); //其他参数
      form.append("category",category.value)
      uploadAudioFile(form).then(response => {
        evaluationResult.value = response.data;
        // 上传完成后取消加载状态
        nextTick(() => {
          loading.close();
        })
      })
      // 更新用户对当前功能的调用频率
      updateToolFrequency(tabIndex.value);
    }
    // 点击图标切换题目
    // 进入页面后直接调用一次获取初始题目
    getRandomSpeechText(category.value).then(response => {
      text.value = response.data;
    })
    // 点击修改语音评测的文本
    function changeText() {
      getRandomSpeechText(category.value).then(response => {
        text.value = response.data;
      })
    }
    // 修改题目类型
    function changeCategory() {
      // 当题目类型修改后 重新调用获取题目的接口
      getRandomSpeechText(category.value).then( response => {
        text.value = response.data;
      })
    }
    // 机器翻译
    function translate() {
      let dom = document.querySelector('.translate-recommend');
      let loading = ElLoading.service({
        text: "相关单词努力生成中...",
        spinner: "",
        target: dom,
      })
      machineTranslate(fromText.value, fromLanguage.value, toLanguage.value).then(response => {
        toText.value = response.data;
      }).catch(error => {
        console.log(error)
      })
      // 完成机器翻译后 获取ai推荐的相关的单词
      getAiRecommendWord(fromText.value,fromLanguage.value,toLanguage.value).then(response => {
        wordList.value = response.data;
        nextTick(() => {
          loading.close()
        })
      }).catch(error => {
        console.log(error)
      })
      // 更新用户对当前功能的调用频率
      updateToolFrequency(tabIndex.value);
    }
    // ai读单词/句子
    function aiReadWord(text) {
      const controller = new AbortController();
      fetchEventSource("/api/aiChat/aiSpeechSynthesis?text=" + text,{
        method: 'GET',
        headers: {
          'content-type': 'application/json',
          'token': localStorage.getItem("token")
        },
        signal: controller.signal,
        openWhenHidden: true,
        onmessage(event) {
          if ( event.data === '&#92n[DONE]' ) {
            // 合成完成 主动断开连接
            controller.abort();
            return;
          }
          base64Array.push(event.data);
          if (!audioPlaying) {
            playNextAudio();
          }
        },
        onclose(event) {
          controller.abort();
        },
        onerror(event) {
          ElMessage.error("对话失败，请重试");
          controller.abort();
        }
      });
    }
    // ai对用户输入文本进行纠错
    function getErrorInfo() {
      let dom = document.querySelector('.word-correct');
      let loading = ElLoading.service({
        text: '错误结果生成中...',
        spinner: "",
        target: dom,
      })
      aiCorrectionError(needCorrectWord.value).then(response => {
        aiCorrectErrorList.value = response.data;
        nextTick(() => {
          loading.close();
        })
      })
      // 更新用户对当前功能的调用频率
      updateToolFrequency(tabIndex.value);
    }
    // 文稿改写
    function textRewrite() {
      let loadingMsg = ElMessage.warning({
        duration: 0,
        message: '文稿改写中...',
        showClose: true,
      })
      aiTextRewrite(initText.value,rewriteLevel.value).then(response => {
        correctText.value = response.data;
        loadingMsg.close();
      })
      // 更新用户对当前功能的调用频率
      updateToolFrequency(tabIndex.value);
    }
    // 公式识别
    function aiFormulaRecognition() {
      formulaRecognition(UID.value).then(response => {
        formula.value = response.data;
      })
      // 更新用户对当前功能的调用频率
      updateToolFrequency(tabIndex.value);
    }
    // 图片转电子稿
    function transformImageToFile(file) {
      pictureDocument(file.data, targetFileType.value, uploadFileType.value).then(response => {
        downloadLink.value = response.data;
        downloadFile()
      })
      // 更新用户对当前功能的调用频率
      updateToolFrequency(tabIndex.value);
    }
    // 图片转文字
    function transformImageToText(file) {
      characterRecognition(file.data).then(response => {
        textResult.value = response.data;
      })
      // 更新用户对当前功能的调用频率
      updateToolFrequency(tabIndex.value);
    }
    // 拍照速算 快速在图片标出那些地方计算正确或错误
    function autoPhotoCalculate(file) {
      UID.value = file.data;
      console.log(file.data)
      photoCalculate(UID.value).then(response => {
        // 遍历data 获取每个式子的位置及计算是否正确
        let objArray = [];
        // 后面绘图所需变量
        var canvas = document.getElementById('myCanvas');
        var ctx = canvas.getContext('2d');
        // 现在被放到canvas中 图片展示的时候宽高改变 所以要先计算缩小的比例在计算公式位置坐标
        let scaleX = canvas.width / imgWidth;
        let scaleY = canvas.height / imgHeight;
        console.log(scaleX)
        console.log(scaleY)
        for ( let i = 0 ; i < response.data.length ; i ++ ) {
          let obj = response.data[i];
          objArray.push({
            leftX: obj.leftX * scaleX,
            leftY: obj.leftY * scaleY,
            rightX: obj.rightX * scaleX,
            rightY: obj.rightY * scaleY,
            isRight: obj.isRight
          })
        }
        var img = new Image();
        getBase64LinkByUID(UID.value).then(response => {
          img.setAttribute('src', `data:image/png;base64,${response.data}`)
          img.onload = function () {
            hasJudged.value = true;
            // 当图片加载完成后 绘制图片到canvas
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
            for (let i = 0; i < objArray.length; i++) {
              // 绘制一个长方形 如果题目计算正确 将边框改为绿色 背景透明 否则边框为红色
              if ( objArray[i].isRight ) {
                ctx.fillStyle = 'rgba(0, 255, 0, 0.5)';
                ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)';
                ctx.lineWidth = 1;
                ctx.strokeRect(objArray[i].leftX, objArray[i].leftY, objArray[i].rightX - objArray[i].leftX, objArray[i].rightY - objArray[i].leftY); // 在指定位置绘制长方形
              } else {
                ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
                ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
                ctx.lineWidth = 1;
                ctx.strokeRect(objArray[i].leftX, objArray[i].leftY, objArray[i].rightX - objArray[i].leftX, objArray[i].rightY - objArray[i].leftY); // 在指定位置绘制长方形
              }
            }
          }
        })
      })
      // 更新用户对当前功能的调用频率
      updateToolFrequency(tabIndex.value);
    }
    /*--------------钩子函数----------------*/
    watch(formula, (newVal, oldVal) => {
      nextTick(() => {
        let element = document.querySelector('.formula-review');
        if ( element ) {
          // 指定元素渲染成数学公式
          MathJax.startup.promise.then(() => {
            MathJax.typesetPromise([element]).then(() => {
              console.log('MathJax completed!')
            })
          });
        }
      })
    })
    // 绘制echarts图表 在未开启后端的情况下此处注释 否则会提前报错导致元素无法加载
    onMounted(() => {
      // 进入页面后获取用户当天对各个功能的使用情况 异步调用
      getToolFrequency().then(response => {
        frequencyList.value = response.data;
        const dom = document.getElementById('echarts');
        const myChart = echarts.init(dom);
        const option = {
          title: {
            text: '调用频率统计图',
            left: 'left'
          },
          // 鼠标悬停显示数据
          tooltip: {
            trigger: 'axis',
            backgroundColor: '#fff', // 悬浮框背景色
            borderColor: '#000', // 悬浮框边框颜色
            borderWidth: 1, // 悬浮框边框宽度
            textStyle: { // 悬浮框文字样式
              color: '#000',
              fontSize: 12
            }
          },
          xAxis: {
            type: 'category',
            data: ['在线翻译','口语练习','文稿纠错','文稿改写','PPT生成','自动批改','图片转文字','图片转电子稿','图片转公式'],
          },
          yAxis: {
            type: 'value',
          },
          series: [
            {
              data: frequencyList.value,
              type: 'line',
              smooth: true
            }
          ]
        };
        myChart.setOption(option);
      })
    })
    // 图片转换
    return {
      isGeneratePPTSpeech,
      isGenerateCover,
      pptAuthor,
      pptType,
      tabIndex,
      fromLanguage,
      toLanguage,
      fromText,
      toText,
      translateList,
      wordList,
      needCorrectWord,
      aiCorrectErrorList,
      formula,
      targetFileType,
      textResult,
      category,
      text,
      rewriteLevel,
      initText,
      correctText,
      hasJudged,
      pptTopic,
      allPPtCover,
      allPPtTheme,
      evaluationResult,
      pptTheme,
      getImageHeightAndWidth,
      textRewrite,
      changeCategory,
      autoPhotoCalculate,
      changeText,
      upload,
      recOpen,
      recStart,
      recStop,
      recPlay,
      translate,
      aiReadWord,
      handleSelect,
      getErrorInfo,
      handleUploadImage,
      aiFormulaRecognition,
      transformImageToFile,
      getUploadFileType,
      copyToClipboard,
      transformImageToText,
      getAiPPT
    }
  }
}
</script>

<template>
  <div class="common-layout">
    <el-container>
      <div class="fix-header">
        <el-header class="header-outer">
          <Header></Header>
        </el-header>
      </div>
      <el-container class="container">
        <div class="content-area">
          <el-aside width="200px" class="aside-area">
            <el-card class="aside-card">
              <el-menu
                  default-active="1"
                  class="el-menu-vertical-demo"
                  @select="handleSelect"
              >
                <el-menu-item index="1">
                  <el-icon><Connection /></el-icon>
                  <span>在线翻译</span>
                </el-menu-item>
                <el-menu-item index="2">
                  <el-icon><ChatRound /></el-icon>
                  <span>口语练习</span>
                </el-menu-item>
                <el-menu-item index="3">
                  <el-icon><Discount /></el-icon>
                  <span>文稿纠错</span>
                </el-menu-item>
                <el-menu-item index="4">
                  <el-icon><EditPen /></el-icon>
                  <span>文稿改写</span>
                </el-menu-item>
                <el-menu-item index="5">
                  <el-icon><DocumentChecked /></el-icon>
                  <span>PPT生成</span>
                </el-menu-item>
                <el-menu-item index="6">
                  <el-icon><Opportunity /></el-icon>
                  <span>自动批改</span>
                </el-menu-item>
                <el-menu-item index="7">
                  <el-icon><DataBoard /></el-icon>
                  <span>图片转文字</span>
                </el-menu-item>
                <el-menu-item index="8">
                  <el-icon><Notebook /></el-icon>
                  <span>图片转电子稿</span>
                </el-menu-item>
                <el-menu-item index="9">
                  <el-icon><DocumentCopy /></el-icon>
                  <span>图片转公式</span>
                </el-menu-item>
              </el-menu>
            </el-card>
          </el-aside>
          <el-main class="main-area">
            <el-card class="main-card">
              <!-- 在线翻译功能 -->
              <div v-if="tabIndex === '1'" class="online-translate">
                <div class="translate">
                  <div class="translate-header">
                    <!-- 用户输入语言种类 -->
                    <el-select v-model="fromLanguage" placeholder="请选择起始语言种类" class="language-select">
                      <el-option v-for="item in translateList" :key="item.value" :label="item.label" :value="item.value"></el-option>
                    </el-select>
                    <el-icon style="margin-top: 10px; margin-left: 15px">
                      <Switch></Switch>
                    </el-icon>
                    <!-- 翻译到的目标语言种类 -->
                    <el-select v-model="toLanguage" placeholder="请选择目标语言种类" class="language-select" style="margin-left: 15px">
                      <el-option v-for="item in translateList" :key="item.value" :label="item.label" :value="item.value"></el-option>
                    </el-select>
                  </div>
                  <div class="translate-body">
                    <el-input v-model="fromText" class="textarea-input" type="textarea" :resize="'none'" :rows="6" placeholder="请输入需要翻译的语句、单词。"></el-input>
                    <el-button :icon="DArrowRight" circle class="translate-button" @click="translate"></el-button>
                    <el-input v-model="toText" class="textarea-input" disabled type="textarea" :resize="'none'" :rows="6" placeholder="翻译"></el-input>
                    <el-icon class="voice-button" @click="aiReadWord(fromText)">
                      <Mic></Mic>
                    </el-icon>
                    <audio src="#" class="audio-play"></audio>
                  </div>
                  <div class="translate-recommend">
                    <span style="font-size: 18px;font-weight: bold" v-if="wordList">相关单词推荐：</span>
                    <div v-for="(item,index) in wordList" :key="index">
                      <div class="word-info">
                        <span style="font-size: 20px">{{item.word}}</span>
                        <span style="font-size:20px;margin-left: 10px">{{item.wordTranslate}}</span>
                        <span style="font-size: 18px;margin-left: 10px">{{item.wordType}}</span>
                      </div>
                      <div style="font-size: 18px;margin-top: 5px;color:#aca08e">{{item.wordExample}}</div>
                    </div>
                  </div>
                </div>
              </div>
              <!-- 口语练习功能 -->
              <div v-else-if="tabIndex === '2'" class="oral-practice-area">
                <!-- 用户朗读部分 -->
                <div class="user-practice">
                  <el-input v-model="text" type="textarea" disabled :resize="'none'" :rows="3" style="font-size: 18px;width: 60%" placeholder="题目生成中，请稍等"></el-input>
                  <el-icon class="refresh-icon" @click="changeText">
                    <RefreshRight></RefreshRight>
                  </el-icon>
                  <div class="oral-function">
                    <div>
                    <span>练习类型：</span>
                    <el-radio-group v-model="category" @change="changeCategory">
                      <el-radio-button label="单词朗读" value="read_word"></el-radio-button>
                      <el-radio-button label="句子朗读" value="read_sentence"></el-radio-button>
                      <el-radio-button label="篇章朗读" value="read_chapter"></el-radio-button>
                    </el-radio-group>
                    </div>
                    <div class="btn-area">
                      <button @click="recOpen" style="background-color:#67c23a; border-color: #67c23a;">打开录音</button>
                      <button  @mousedown="recStart" @mouseup="recStop" style="background-color: #409ED7; border-color: #409ED7;">按住录音</button>
                      <button style="background-color:#909399; border-color: #909399;" @click="aiReadWord(text)">标准读音</button>
                      <button  @click="recPlay" style="background-color:#e6a23c; border-color: #e6a23c;">录音回听</button>
                    </div>
                  </div>
                </div>
                <!-- 语音评测结果部分 -->
                <div class="oral-result">
                  <span style="font-size: 18px;font-weight: bold">评测结果如下</span>
                  <el-carousel height="350px">
                    <el-carousel-item v-for="(item,index) in evaluationResult" :key="index">
                      <el-form style="width: 100%;height: 100%" :label-position="'left'" label-width="auto">
                        <el-form-item label="评测文本：">
                          <span><strong>{{item.text}}</strong></span>
                        </el-form-item>
                        <el-form-item label="是否有效：">
                          <span :class="item.isRejected === 1 ? 'red' : 'green'"><strong>{{item.isRejected === 1 ? '检测为乱读，以下评分只作为参考' : '检测为正常'}}</strong></span>
                        </el-form-item>
                        <el-form-item label="准确度得分">
                          <el-tag effect="dark" type="info">{{item.accuracyScore < 0 ? '暂无' : item.accuracyScore}}</el-tag>
                        </el-form-item>
                        <el-form-item label="标准度得分">
                          <el-tag effect="dark" type="primary">{{item.standardScore < 0 ? '暂无' : item.standardScore}}</el-tag>
                        </el-form-item>
                        <el-form-item label="流畅度得分">
                          <el-tag effect="dark" type="success">{{item.fluencyScore < 0 ? '暂无' : item.fluencyScore}}</el-tag>
                        </el-form-item>
                        <el-form-item label="完整度得分">
                          <el-tag effect="dark" type="warning">{{item.integrityScore < 0 ? '暂无' : item.integrityScore}}</el-tag>
                        </el-form-item>
                        <el-form-item label="总分">
                          <el-tag effect="dark" type="danger">{{item.totalScore < 0 ? '暂无' : item.totalScore}}</el-tag>
                        </el-form-item>
                        <el-form-item label="结果">
                          <el-tag effect="dark">{{item.rejectedType}}</el-tag>
                        </el-form-item>
                      </el-form>
                    </el-carousel-item>
                  </el-carousel>
                </div>
              </div>
              <div v-else-if="tabIndex === '3'" class="word-correct">
                <el-input v-model="needCorrectWord" type="textarea" :rows="6" placeholder="请输入要纠错的语句" resize="none" class="word-correct-textarea"></el-input>
                <div class="middle-area">
                  <el-tag effect="dark" type="danger" class="word-correct-text">纠错结果：</el-tag>
                  <el-button type="success" @click="getErrorInfo">查询错误</el-button>
                </div>
                <div class="correct-area">
                  <el-carousel height="230px" class="carousel-area">
                    <el-carousel-item v-for="(item,index) in aiCorrectErrorList" :key="index" :loop="false" :autoplay="false">
                      <div>
                        <div class="correct-title">{{item.type}}</div>
                        <el-tag class="correct-tips" type="info">纠错语句按照 [错误位置，错误语句，改正后语句，详细错误信息] 的格式使用逗号分隔。</el-tag>
                        </div>
                      <div class="correct-content">
                        <div v-for="(it,idx) in item.errorDetails" :key="idx">{{it}}</div>
                      </div>
                    </el-carousel-item>
                  </el-carousel>
                </div>
              </div>
              <!-- 文稿改写 -->
              <div v-else-if="tabIndex === '4'" class="text-rewrite-area">
                <div style="margin-bottom: 5px">
                  <span style="font-size: 18px;font-weight: bold;">改写等级：</span>
                  <el-radio-group v-model="rewriteLevel">
                    <el-radio-button label="1级" value="<L1>"></el-radio-button>
                    <el-radio-button label="2级" value="<L2>"></el-radio-button>
                    <el-radio-button label="3级" value="<L3>"></el-radio-button>
                    <el-radio-button label="4级" value="<L4>"></el-radio-button>
                    <el-radio-button label="5级" value="<L5>"></el-radio-button>
                    <el-radio-button label="6级" value="<L6>"></el-radio-button>
                  </el-radio-group>
                </div>
                <el-input v-model="initText" type="textarea" :resize="'none'" :rows="7" placeholder="请输入需要改写的内容。" style="font-size: 18px"></el-input>
                <div class="text-rewrite-btn">
                  <el-button type="primary" @click="textRewrite">点击改写</el-button>
                  <el-button type="success" @click="copyToClipboard(correctText)">复制内容到剪切板</el-button>
                </div>
                <el-input v-model="correctText" disabled type="textarea" :resize="'none'" :rows="7" placeholder="此处将展示改后内容。" style="font-size: 18px"></el-input>
              </div>
              <!-- PPT生成 -->
              <div v-else-if="tabIndex === '5'" class="ai-ppt-area">
                <el-select v-model="pptTheme" placeholder="请选择PPT主题" style="width: 30%;">
                  <el-option
                      v-for="item in allPPtTheme"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                  />
                </el-select>
                <!-- 展示ppt主题 -->
                <el-carousel height="240px" motion-blur style="margin-top: 10px">
                  <el-carousel-item v-for="(item,index) in allPPtCover" :key="index">
                    <el-image :src="item" alt="" style="width: 100%;height: 100%"></el-image>
                  </el-carousel-item>
                </el-carousel>
                <div class="ai-ppt-info">
                  <el-form :label-position="'left'" label-width="auto">
                    <el-form-item label="请选择ppt生成类型">
                      <el-radio-group v-model="pptType">
                        <el-radio-button label="话题生成" value="topic" />
                        <el-radio-button label="文本生成" value="text" />
                        <el-radio-button label="程序判断" value="auto" />
                      </el-radio-group>
                    </el-form-item>
                    <el-form-item label="请输入ppt作者名">
                      <el-input v-model="pptAuthor" placeholder="请输入ppt作者名，可为空"></el-input>
                    </el-form-item>
                    <el-form-item label="是否生成PPT演讲备注">
                      <el-switch
                          v-model="isGeneratePPTSpeech"
                          class="ml-2"
                          style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
                      />
                    </el-form-item>
                    <el-form-item label="是否生成封面图">
                      <el-switch
                          v-model="isGenerateCover"
                          class="ml-2"
                          style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
                      />
                    </el-form-item>
                  </el-form>
                  <div class="submit-info">
                    <el-input v-model="pptTopic" type="textarea" :resize="'none'" :rows="4" placeholder="请输入对生成的ppt的要求" style="font-size: 16px"></el-input>
                    <el-button type="primary" class="submit-button" @click="getAiPPT">点击生成</el-button>
                    <el-button type="warning" class="submit-button" style="margin-right: 10px">重置表单</el-button>
                  </div>
                </div>
              </div>
              <!-- 自动批改 -->
              <div v-else-if="tabIndex === '6'" class="auto-correct">
                <div class="auto-correct-image-upload" v-if="!hasJudged">
                  <el-upload
                      drag
                      :on-success="autoPhotoCalculate"
                      action="/api/aiChat/getBase64Link"
                      :before-upload="getImageHeightAndWidth"
                  >
                    <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                    <div class="el-upload__text">
                      拖拽或者 <em>点击以上传图片文件</em>
                    </div>
                    <template #tip>
                      <div class="el-upload__tip">
                        jpg/png 文件大小不超过 500kb
                      </div>
                    </template>
                  </el-upload>
                </div>
                <div class="auto-correct-result">
                  <canvas id="myCanvas" width="900" height="500"></canvas>
                </div>
              </div>
              <!-- 图片转文字 -->
              <div v-else-if="tabIndex === '7'" class="image-to-text-area">
                <div class="image-to-text-upload">
                  <el-upload
                      drag
                      :on-success="transformImageToText"
                      action="/api/aiChat/getBase64Link"
                      multiple
                  >
                    <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                    <div class="el-upload__text">
                      拖拽或者 <em>点击以上传图片文件</em>
                    </div>
                    <template #tip>
                      <div class="el-upload__tip">
                        jpg/png 文件大小不超过 500kb
                      </div>
                    </template>
                  </el-upload>
                </div>
                <div class="image-to-text-buttons">
                  <el-button type="success" @click="copyToClipboard(textResult)">复制到剪切板</el-button>
                  <el-button type="info">清空</el-button>
                </div>
                <div class="image-to-text-result">
                  <el-input v-model="textResult" type="textarea" :resize="'none'" style="font-size: 17px" :rows="7"></el-input>
                </div>
              </div>
              <!-- 图片转电子稿 -->
              <div v-else-if="tabIndex === '8'" class="wps-area">
                <div class="wps-box">
                  <div class="wps-image-upload">
                    <div>
                      <span>目标文件类型：</span>
                      <el-radio-group v-model="targetFileType">
                        <el-radio-button label="excel" value="0"></el-radio-button>
                        <el-radio-button label="doc" value="1"></el-radio-button>
                        <el-radio-button label="ppt" value="2"></el-radio-button>
                      </el-radio-group>
                    </div>
                    <el-upload
                        style="margin-top: 10px"
                        drag
                        :before-upload="getUploadFileType"
                        :on-success="transformImageToFile"
                        action="/api/aiChat/getBase64Link"
                    >
                      <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                      <div class="el-upload__text">
                        拖拽或者 <em>点击以上传图片文件</em>
                      </div>
                      <template #tip>
                        <div class="el-upload__tip">
                          jpg/png 文件大小不超过 500kb
                        </div>
                      </template>
                    </el-upload>
                  </div>
                </div>
              </div>
              <!-- 图片转公式 -->
              <div v-else-if="tabIndex === '9'" class="formula-area">
                <div class="formula-top">
                  <div class="title-div">
                    <div style="font-size: 19px;font-weight: bold;margin-top: -10px">左侧在线编辑</div>
                    <div style="font-size: 19px;font-weight: bold;margin-top: -10px;color: #9199A1">右侧实时预览</div>
                  </div>
                  <div class="formula-box">
                    <div class="formula-edit">
                      <el-input v-model="formula" type="textarea" :resize="'none'" :rows="7" placeholder="请输入latex公式" style="font-size: 17px"></el-input>
                    </div>
                    <el-button :icon="DArrowRight" circle class="formula-button" @click="aiFormulaRecognition"></el-button>
                    <div class="formula-review">
                      {{formula}}
                    </div>
                  </div>
                </div>
                <div class="formula-img-upload">
                  <div style="font-size: 19px;font-weight: bold;">图片上传</div>
                  <el-upload
                      class="upload-demo"
                      drag
                      :on-success="handleUploadImage"
                      action="/api/aiChat/getBase64Link"
                  >
                    <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                    <div class="el-upload__text">
                      拖拽或者 <em>点击以上传图片文件</em>
                    </div>
                    <template #tip>
                      <div class="el-upload__tip">
                        jpg/png 文件大小不超过 500kb
                      </div>
                    </template>
                  </el-upload>
                </div>
              </div>
            </el-card>
          </el-main>
        </div>
        <el-card class="echarts-card" id="echarts"></el-card>
      </el-container>
    </el-container>
  </div>
</template>

<style lang="less" scoped>
.common-layout {
  // 顶部导航栏
  .fix-header {
    position: fixed;
    width: 100%;
    z-index: 900;
    box-shadow: 0 4px 8px 0 rgba(7,17,27,0.1);
    .header-outer {
      height: 100%;
      // 改变盒子背景 略灰一点
      background-color: #fff;
      // 改变外部盒子边界线便于区分
      border-bottom: 2px solid #eee;
      // 设置盒子底部阴影
      box-shadow: 0 2px 8px 0 rgba(7, 17, 27, 0.06);
    }
  }
  .container {
    display: flex;
    flex-direction: column;
    align-items: center;
    .content-area {
      width: 1200px;
      margin: 125px auto;
      position: relative;
      display: flex;

      .aside-area {
        border-radius: 6px;

        .aside-card {
          border-radius: 10px;
          height: 505px;
          .el-menu--vertical {
            box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.1);
            --el-menu-hover-text-color: #000 !important;
            .el-menu-item.is-active {
              color: #2A71C8;
            }
            .el-menu-item:hover {
              color: #000 !important;
            }
            .el-menu-item:hover .svg-icon {
              fill: #000 !important;
            }
            .el-sub-menu.is-active:not(.is-opened) .el-sub-menu__title {
              color: #2A71C8 !important;
            }
            .el-sub-menu__title:hover {
              color: #000 !important;
            }
          }
          :deep(.el-card__body) {
            padding: 0;
          }
        }
      }

      .main-area {
        height: 100%;
        background-color: #fff;
        .main-card {
          margin-top: -20px;
          height: 505px;
          .online-translate {
            display: flex;
            .translate {
              height: 50%;
              width: 100%;
              .translate-header {
                display: flex;
                .language-select {
                  width: 20%;
                }
              }
              .translate-body {
                display: flex;
                position: relative;
                .textarea-input {
                  margin-top: 10px;
                  font-size: 20px;
                }
                .translate-button {
                  top: 45%;
                  left: 48%;
                  position: absolute;
                  z-index: 1;
                }
                .voice-button {
                  cursor: pointer;
                  position: absolute;
                  top: 86%;
                  left: 47%;
                }
                .audio-play {
                  position: absolute;
                  opacity: 0;
                  visibility: hidden;
                }
              }
              .translate-recommend {
                margin-top: 10px;
                width: 100%;
                height: 230px;
                .word-info {
                  margin-top: 10px;
                }
              }
            }
          }
          .oral-practice-area {
            .user-practice {
              display: flex;
              position: relative;
              .refresh-icon {
                position: absolute;
                left: 57%;
                top: 75%;
                cursor: pointer;
              }
              .oral-function {
                margin-left: 10px;
                .btn-area {
                  margin-top: 20px;
                  display: flex;
                  align-items: center;
                  justify-content: space-between;
                  button {
                    display: inline-block;
                    line-height: 1;
                    white-space: nowrap;
                    cursor: pointer;
                    background: #fff;
                    border: 1px solid #dcdfe6;
                    color: #fff;
                    -webkit-appearance: none;
                    text-align: center;
                    box-sizing: border-box;
                    outline: none;
                    margin: 0;
                    transition: .1s;
                    font-weight: 500;
                    -moz-user-select: none;
                    -webkit-user-select: none;
                    -ms-user-select: none;
                    padding: 10px 10px;
                    font-size: 14px;
                    border-radius: 4px;
                  }
                }
              }
            }
          }
          .word-correct {
            .word-correct-textarea {
              font-size: 20px;
            }
            .middle-area {
              display: flex;
              justify-content: space-between;
              margin-top: 10px;
              .word-correct-text {
                font-size: 18px;
                font-weight: bold;
              }
            }
            .correct-area {
              .carousel-area {
                display: flex;
                flex-direction: column;
                margin-top: 10px;
                .correct-title {
                  font-size: 19px;
                }
                .correct-tips {
                  margin-top: 10px;
                }
                .correct-content {
                  margin-top: 10px;
                  color: red;
                  font-size: 17px;
                }
              }
            }
          }
          .text-rewrite-area {
            .text-rewrite-btn {
              margin-top: 5px;
              display: flex;
              align-items: center;
              justify-content: center;
              margin-bottom: 5px;
            }
          }
          .ai-ppt-area {
            width: 100%;
            height: 100%;
            .ai-ppt-info {
              margin-top: 10px;
              display: flex;
              justify-content: space-between;
              .submit-info {
                width: 50%;
                .submit-button {
                  margin-top: 25px;
                  float: right;
                }
              }
            }
          }
          .auto-correct {
            .auto-correct-result {
              width: 100%;
              height: 100%;
            }
          }
          .wps-area {
            display: flex;
            flex-direction: column;
            height: 320px;
            .wps-box {
              height: 80%;
              overflow: hidden;
            }
          }
          .formula-area {
            display: flex;
            flex-direction: column;
            width: 100%;
            .formula-top {
              width: 100%;
              .title-div {
                display: flex;
                justify-content: space-between;
              }
              .formula-box {
                width: 100%;
                margin-top: 10px;
                display: flex;
                font-size: 18px;
                position: relative;
                .formula-edit {
                  width: 50%;
                  height: 200px;
                }
                .formula-button {
                  position: absolute;
                  top: 40%;
                  left: 48%;
                }
                .formula-review {
                  width: 50%;
                  height: 187px;
                  font-size: 17px;
                  box-shadow: 0 0 0 1px #dcdfe6;
                  border-radius: 4px;
                  display: flex;
                  align-items: center;
                  justify-content: center;
                  background-color: #F5F7FA;
                }
              }
            }
            .formula-img-upload {
              width: 100%;
            }
          }
        }
      }
    }
    .echarts-card {
      width: 1185px;
      left: -.5%;
      margin: -120px auto;
      position: relative;
      height: 300px;
    }
  }
}
.red {
  color: red;
}
.green {
  color: green;
}
</style>